package com.xbongbong.saas.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.constant.MessageConstant;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasAppEntity;
import com.xbongbong.paas.domain.entity.PaasFormExplainEntity;
import com.xbongbong.paas.domain.entity.PaasProcessDataEntity;
import com.xbongbong.paas.domain.entity.ext.PaasFormEntityExt;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.FlowStatusEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.field.ItemPoJo;
import com.xbongbong.paas.field.ReceivablePeriodPojo;
import com.xbongbong.paas.help.CommonHelp;
import com.xbongbong.paas.log.MongoLogHelp;
import com.xbongbong.paas.log.constant.LogMemoConstant;
import com.xbongbong.paas.model.PaasAppModel;
import com.xbongbong.paas.model.PaasFormExplainModel;
import com.xbongbong.paas.model.PaasFormModel;
import com.xbongbong.paas.model.PaasProcessDataModel;
import com.xbongbong.paas.pojo.CodeValuePojo;
import com.xbongbong.paas.pojo.KeyAndValuePojo;
import com.xbongbong.paas.redis.PaasRedisHelper;
import com.xbongbong.paas.redis.RedisPrefixConstant;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.util.JsonHelperUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.toolbox.wrap.BaseDTO;
import com.xbongbong.paas.util.ExplainUtil;
import com.xbongbong.pro.config.ProBaseConfig;
import com.xbongbong.pro.constant.I18nStringConstant;
import com.xbongbong.pro.constant.SymbolConstant;
import com.xbongbong.pro.enums.DistributorMarkEnum;
import com.xbongbong.pro.enums.ErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.FundsSetErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.enums.fund.enums.FundSetMenuEnum;
import com.xbongbong.pro.enums.fund.enums.ManageTypeEnum;
import com.xbongbong.pro.enums.fund.enums.ModelTypeEnum;
import com.xbongbong.pro.enums.fund.enums.PayMethodFundSetEnum;
import com.xbongbong.pro.fundset.pojo.FundSetHandleExplainPojo;
import com.xbongbong.pro.fundset.pojo.FundSetMenuPojo;
import com.xbongbong.pro.fundset.pojo.FundSetPayPojo;
import com.xbongbong.pro.fundset.pojo.FundSetPeriodFilterPojo;
import com.xbongbong.pro.fundset.pojo.FundSetPeriodRulePojo;
import com.xbongbong.pro.fundset.pojo.FundSetTransitionPojo;
import com.xbongbong.pro.fundset.pojo.PeriodFilterPojo;
import com.xbongbong.pro.fundset.pojo.dto.FundSetConditionAttrDTO;
import com.xbongbong.pro.fundset.pojo.dto.FundSetDTO;
import com.xbongbong.pro.fundset.pojo.dto.FundSetListDTO;
import com.xbongbong.pro.fundset.pojo.dto.FundSetPayDTO;
import com.xbongbong.pro.fundset.pojo.dto.FundSetPaySaveDTO;
import com.xbongbong.pro.fundset.pojo.dto.FundSetPaymentSaveDTO;
import com.xbongbong.pro.fundset.pojo.vo.FundSetConditionAttrInfoVO;
import com.xbongbong.pro.fundset.pojo.vo.FundSetConditionAttrVO;
import com.xbongbong.pro.fundset.pojo.vo.FundSetListVO;
import com.xbongbong.pro.fundset.pojo.vo.FundSetPayListVO;
import com.xbongbong.pro.fundset.pojo.vo.FundSetPayVO;
import com.xbongbong.pro.fundset.pojo.vo.FundSetPaymentItemVO;
import com.xbongbong.pro.fundset.pojo.vo.FundSetPaymentSaveVO;
import com.xbongbong.pro.fundset.pojo.vo.FundSetVO;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.ParameterConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.entity.FundSetEntity;
import com.xbongbong.saas.domain.entity.ext.InvoiceEntityExt;
import com.xbongbong.saas.domain.entity.ext.OutstockEntityExt;
import com.xbongbong.saas.domain.entity.ext.PaymentSheetEntityExt;
import com.xbongbong.saas.enums.CompanyConfigEnum;
import com.xbongbong.saas.enums.OperateModuleTypeEnum;
import com.xbongbong.saas.enums.OperateTypeEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.ContractEnum;
import com.xbongbong.saas.enums.business.OrderEnum;
import com.xbongbong.saas.enums.dictionary.OrderTypeEnum;
import com.xbongbong.saas.model.FundSetModel;
import com.xbongbong.saas.model.InvoiceModel;
import com.xbongbong.saas.model.OutstockModel;
import com.xbongbong.saas.model.PaymentSheetModel;
import com.xbongbong.saas.service.FundSetService;
import com.xbongbong.saas.service.toolbox.help.FundSetHelp;
import com.xbongbong.sys.domain.entity.CompanyConfigEntity;
import com.xbongbong.sys.model.CompanyConfigModel;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author zcp
 * @version v1.0
 * @since v1.0
 */
@Service("fundSetService")
public class FundSetServiceImpl implements FundSetService {
    private static final Logger LOG = LoggerFactory.getLogger(FundSetServiceImpl.class);
    @Resource
    private FundSetHelp fundSetHelp;
    @Resource
    private FundSetModel fundSetModel;
    @Resource
    private PaasFormModel paasFormModel;
    @Resource
    private PaasFormExplainModel paasFormExplainModel;
    @Resource
    private PaasRedisHelper paasRedisHelper;
    @Resource
    private PaasProcessDataModel paasProcessDataModel;
    @Resource
    private MongoLogHelp mongoLogHelp;
    @Resource
    private CompanyConfigModel companyConfigModel;
    @Resource
    private PaasAppModel paasAppModel;
    @Resource
    private CommonHelp commonHelp;
    @Resource
    private PaymentSheetModel paymentSheetModel;
    @Resource
    private InvoiceModel invoiceModel;
    @Resource
    private OutstockModel outstockModel;

    @Override
    public FundSetListVO getMenuList(FundSetListDTO fundSetListDTO) throws XbbException {
        FundSetListVO fundSetListVO = new FundSetListVO();
        try {
            List<FundSetMenuPojo> list = fundSetHelp.getFundSetMenu(XbbRefTypeEnum.CRM.getCode());
            // 经销商应用关闭，支付设置不显示
            PaasAppEntity distributorAppEntity = paasAppModel.getByAlias(XbbRefTypeEnum.DISTRIBUTOR.getAlias(), fundSetListDTO.getCorpid());
            if (Objects.isNull(distributorAppEntity) || distributorAppEntity.getEnable() == 0) {
                list.removeIf(item -> (Objects.equals(item.getType(), FundSetMenuEnum.PAY_RULE.getType()) || Objects.equals(item.getType(), FundSetMenuEnum.CREDIT_RULE.getType())));
            }
            fundSetListVO.setList(list);
        } catch (Exception e) {
            LOG.error("获取资金设置菜单失败");
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return fundSetListVO;
    }

    @Override
    public FundSetPaymentItemVO paymentItem(BaseDTO baseDTO) throws XbbException {
        FundSetPaymentItemVO fundSetPaymentItemVO = new FundSetPaymentItemVO();
        try {
            String corpid = baseDTO.getCorpid();
            //把资金设置相关信息从数据库读取出
            FundSetEntity setEntity = fundSetModel.getByRefType(corpid, XbbRefTypeEnum.CRM.getCode(), FundSetMenuEnum.RECEIVABLE_RULES.getType());
            if (Objects.nonNull(setEntity)) {
                //设置相关信息置入缓存
                saveSetInfoToRedis(corpid, setEntity);
                List<FundSetPeriodFilterPojo> periodFilter = JsonHelperUtil.parseArray(setEntity.getPeriodFilter(), FundSetPeriodFilterPojo.class);
                List<FundSetPeriodFilterPojo> periodFilterView = new ArrayList<>();
                ManageTypeEnum manageTypeEnum = ManageTypeEnum.getByCode(setEntity.getManageType());
                if (manageTypeEnum != null) {
                    switch (manageTypeEnum) {
                        case CUSTOMER:
                        case CONTRACT:
                            Map<Long, FundSetPeriodFilterPojo> formFilterMap = periodFilter.stream().collect(Collectors.toMap(pojo -> pojo.getFormId(), pojo -> pojo));
                            List<PaasFormEntityExt> paasFormEntityExtList = paasFormModel.getEnableFormList(corpid, manageTypeEnum.getXbbRefTypeEnum().getCode());
                            for (PaasFormEntityExt entityExt : paasFormEntityExtList) {
                                Long formId = entityExt.getId();
                                FundSetPeriodFilterPojo fundSetPeriodFilterPojo = formFilterMap.getOrDefault(formId, new FundSetPeriodFilterPojo());
                                fundSetPeriodFilterPojo.setFormId(entityExt.getId());
                                fundSetPeriodFilterPojo.setFormName(entityExt.getName());
                                String attrName = fundSetPeriodFilterPojo.getAttrName();
                                String title = "";
                                if (StringUtil.isNotEmpty(attrName)) {
                                    title = String.format(I18nMessageUtil.getMessage(MessageConstant.FUND_SET_PERIOD_FILTER_TITLE), attrName);
                                }
                                fundSetPeriodFilterPojo.setTitle(title);
                                periodFilterView.add(fundSetPeriodFilterPojo);
                            }
                            break;
                        default:
                            periodFilterView = periodFilter;
                            break;
                    }
                }
                fundSetPaymentItemVO.setPeriodFilter(periodFilterView);
            } else {
                setEntity = new FundSetEntity(XbbRefTypeEnum.CRM.getCode());
            }
            BeanUtil.copyProperties(setEntity, fundSetPaymentItemVO);
            fundSetPaymentItemVO.setModelType(setEntity.getSysLong10());
            //封装modelTypeItem等
            List<KeyAndValuePojo> modelTypeItem = new ArrayList<>();
            for (ModelTypeEnum cache : ModelTypeEnum.values()) {
                KeyAndValuePojo keyAndValuePojo = new KeyAndValuePojo(cache.getCode(), cache.getName());
                modelTypeItem.add(keyAndValuePojo);
            }
            List<KeyAndValuePojo> manageTypeItem = new ArrayList<>();
            for (ManageTypeEnum cache : ManageTypeEnum.values()) {
                KeyAndValuePojo keyAndValuePojo = new KeyAndValuePojo(cache.getCode().longValue(), cache.getName());
                manageTypeItem.add(keyAndValuePojo);
            }
            fundSetPaymentItemVO.setModelTypeItem(modelTypeItem);
            fundSetPaymentItemVO.setManageTypeItem(manageTypeItem);
        } catch (Exception e) {
            LOG.error("获取应收规则信息失败");
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return fundSetPaymentItemVO;
    }

    @Override
    public FundSetConditionAttrVO conditionAttr(FundSetConditionAttrDTO fundSetConditionAttrDTO) throws XbbException {
        String corpid = fundSetConditionAttrDTO.getCorpid();
        Long formId = fundSetConditionAttrDTO.getFormId();
        PaasFormEntityExt paasFormEntity = paasFormModel.getByKey(formId, corpid);
        if (paasFormEntity == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_NOT_EXIST);
        }
        PaasFormExplainEntity explainEntity = paasFormExplainModel.getByFormId(formId, corpid);
        if (explainEntity == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
        }
        List<FieldAttrEntity> explainList = JSONArray.parseArray(explainEntity.getExplains(), FieldAttrEntity.class);
        List<FundSetConditionAttrInfoVO> list = new ArrayList<>();
        //bugId：37285，订货单(201，且distributorMark为1)
        boolean orderFlag = Objects.equals(paasFormEntity.getDistributorMark(), DistributorMarkEnum.DISTRIBUTOR.getCode()) && Objects.equals(paasFormEntity.getBusinessType(), XbbRefTypeEnum.CONTRACT.getCode());
        for (FieldAttrEntity fieldAttrEntity : explainList) {
            Integer fieldType = fieldAttrEntity.getFieldType();
            //bugId：37285，非订货单则获取所有下拉类型字段，订货单则只获取下单类型
            boolean flag = (!orderFlag && Objects.nonNull(fieldType) && (Objects.equals(FieldTypeEnum.COMBO.getType(), fieldType) || Objects.equals(FieldTypeEnum.RADIO_GROUP.getType(), fieldType))) || (orderFlag && Objects.equals(fieldAttrEntity.getAttr(), OrderEnum.TYPE.getAttr()));
            if (flag) {
                List<ItemPoJo> items = fieldAttrEntity.getItems();
                if (CollectionsUtil.isEmpty(items)) {
                    continue;
                }
                List<CodeValuePojo> item = new ArrayList<>();
                for (ItemPoJo itemPoJo : items) {
                    CodeValuePojo codeValuePojo = new CodeValuePojo(itemPoJo.getValue(), itemPoJo.getText());
                    item.add(codeValuePojo);
                }
                FundSetConditionAttrInfoVO infoVO = new FundSetConditionAttrInfoVO();
                infoVO.setAttr(fieldAttrEntity.getAttr());
                infoVO.setAttrName(fieldAttrEntity.getAttrName());
                infoVO.setItem(item);
                list.add(infoVO);
            }
        }
        FundSetConditionAttrVO fundSetConditionAttrVO = new FundSetConditionAttrVO();
        fundSetConditionAttrVO.setList(list);
        return fundSetConditionAttrVO;
    }

    @Override
    public FundSetPaymentSaveVO paymentSave(FundSetPaymentSaveDTO fundSetPaymentSaveDTO) throws XbbException {
        try {
            String corpid = fundSetPaymentSaveDTO.getCorpid();
            FundSetEntity setEntity = fundSetModel.getByRefType(corpid, XbbRefTypeEnum.CRM.getCode(), FundSetMenuEnum.RECEIVABLE_RULES.getType());
            Long oldModelType = ModelTypeEnum.PLAN.getCode();
            Integer oldManageType = ManageTypeEnum.NONE.getCode();
            Long now = DateTimeUtil.getInt();
            if (Objects.isNull(setEntity)) {
                setEntity = new FundSetEntity(XbbRefTypeEnum.CRM.getCode());
                setEntity.setCorpid(corpid);
                setEntity.setAddTime(now);
            } else {
                oldModelType = setEntity.getSysLong10();
                oldManageType = setEntity.getManageType();
            }
            Long modelType = fundSetPaymentSaveDTO.getModelType();
            ModelTypeEnum modelTypeEnum = ModelTypeEnum.getByCode(modelType);
            //保存条件校验，及获取是否更改模式（有可能只是设置了账期条件，未更改模式）
            boolean changeModelFlag = checkSet(fundSetPaymentSaveDTO, modelTypeEnum, oldModelType);
            //条件置入并保存
            setEntity.setSysLong10(fundSetPaymentSaveDTO.getModelType());
            setEntity.setManageType(fundSetPaymentSaveDTO.getManageType());
            List<FundSetPeriodFilterPojo> periodFilter = fundSetPaymentSaveDTO.getPeriodFilter();
            setEntity.setPeriodFilter(JSONArray.toJSONString(periodFilter));
            setEntity.setCreatorId(fundSetPaymentSaveDTO.getUserId());
            setEntity.setUpdateTime(now);
            fundSetModel.save(setEntity);
            //设置相关信息置入缓存
            saveSetInfoToRedis(corpid, setEntity);
            //切换模式或更改管理方式后，处理①客户、合同模板的应收账期字段；②销项发票的关联回款类型、回款单、应收款；③回款单、应收款的开票金额
            updateExplain(fundSetPaymentSaveDTO, corpid, modelTypeEnum, changeModelFlag, oldManageType);

            // 记录日志
            ModelTypeEnum oldModelTypeEnum = ModelTypeEnum.getByCode(oldModelType);
            String oldName = Objects.isNull(oldModelTypeEnum)? "": oldModelTypeEnum.getName();
            String userId = fundSetPaymentSaveDTO.getUserId();
            String loginUserName = fundSetPaymentSaveDTO.getLoginUserName();
            String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.FUND_SET_CHANGE_MODEL_TYPE), loginUserName, oldName, modelTypeEnum.getName());
            mongoLogHelp.buildLog(corpid, userId, loginUserName, OperateModuleTypeEnum.FUND_SET, OperateTypeEnum.SET, setEntity.getId().toString(), "", memo, fundSetPaymentSaveDTO.getHttpHeader());
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("应收规则保存失败", e);
            throw new XbbException(FundsSetErrorCodeEnum.API_ERROR_248007, FundsSetErrorCodeEnum.API_ERROR_248007.getMsg());
        }
        FundSetPaymentSaveVO fundSetPaymentSaveVO = new FundSetPaymentSaveVO();
        return fundSetPaymentSaveVO;
    }

    @Override
    public Long getModelType(String corpid, XbbRefTypeEnum xbbRefTypeEnum) {
        return fundSetModel.getModelType(corpid, xbbRefTypeEnum);
    }

    @Override
    public Integer getManageType(String corpid, XbbRefTypeEnum xbbRefTypeEnum) {
        String key = corpid + SymbolConstant.UNDERLINE + XbbRefTypeEnum.CRM.getCode();
        String manageTypeStr = paasRedisHelper.getValue(RedisPrefixConstant.FUND_SET_MANAGE_TYPE, key);
        if (StringUtil.isNotEmpty(manageTypeStr)) {
            return StringUtil.toInt(manageTypeStr);
        }
        //把资金设置相关信息从数据库读取出，再保存入缓存
        FundSetEntity setEntity = getToRedis(corpid, xbbRefTypeEnum);
        return setEntity.getManageType();
    }

    /**
     * 生成应收账期方法
     *
     * @param corpid 公司id
     * @param time 回款计划的预计回款日期、发票的开票日期、出库的出库日期
     * @param linkCustomerId 应收款关联的客户id
     * @param linkContractId 应收款关联的合同id
     * @param generationDate 应收生成日期
     * @return
     * @throws XbbException
     */
    @Override
    public PeriodFilterPojo getPeriodFilter4Payment(String corpid, Long time, Long linkCustomerId, Long linkContractId, Long generationDate) throws XbbException {
        return fundSetHelp.getPeriodFilter4Payment(corpid, time, linkCustomerId, linkContractId, generationDate);
    }

    @Override
    public List<FieldAttrEntity> formatPeriod(String corpid, Integer businessType, Long formId, List<FieldAttrEntity> explainList) throws XbbException {
        return fundSetHelp.formatPeriod(corpid, businessType, formId, explainList);
    }

    @Override
    public ReceivablePeriodPojo formatPeriod4DistributorOrder(String corpid, PaasFormExplainEntity paasFormExplainEntity) throws XbbException {
        if (!Objects.equals(paasFormExplainEntity.getBusinessType(), XbbRefTypeEnum.CONTRACT.getCode())) {
            return null;
        }
        //不会为null，内部已经处理
        FundSetEntity setEntity = getToRedis(corpid, XbbRefTypeEnum.CRM);
        Long modelType = setEntity.getSysLong10();
        Integer manageType = setEntity.getManageType();
        boolean flag = Objects.equals(ModelTypeEnum.PLAN.getCode(), modelType) || Objects.equals(ManageTypeEnum.NONE.getCode(), manageType) || Objects.equals(ManageTypeEnum.CORP.getCode(), manageType);
        if (flag) {
            //“手动创建应收”模式，或管理方式为无账期/企业统一管理账期，则不用处理默认账期
            return null;
        }
        Long formId = paasFormExplainEntity.getFormId();
        //给经销商端的订货单塞入默认账期
        String typeAttr = OrderEnum.TYPE.getAttr();
        Map<String, FieldAttrEntity> explainMap = ExplainUtil.getExplainMapByAttr(paasFormExplainEntity.getExplains(), typeAttr);
        if (Objects.isNull(explainMap) || explainMap.size() == 0) {
            return null;
        }
        //此处只判断合同..如果是合同，则需要管理方式为根据合同管理账期。否则，获取不到默认账期（因为是按照其他方式生成应收）
        if (Objects.equals(ManageTypeEnum.CUSTOMER.getCode(), manageType)) {
            //根据客户管理账期，不用处理合同的账期字段
            return null;
        }
        List<FundSetPeriodFilterPojo> periodFilter = JsonHelperUtil.parseArray(setEntity.getPeriodFilter(), FundSetPeriodFilterPojo.class);
        if (CollectionsUtil.isEmpty(periodFilter)) {
            //为空则当做无账期
            return null;
        }
        FundSetPeriodFilterPojo fundSetPeriodFilterPojo = null;
        for (FundSetPeriodFilterPojo setPeriodFilterPojo : periodFilter) {
            if (Objects.equals(setPeriodFilterPojo.getFormId(), formId)) {
                fundSetPeriodFilterPojo = setPeriodFilterPojo;
                break;
            }
        }
        List<FundSetPeriodRulePojo> rule = Objects.isNull(fundSetPeriodFilterPojo) ? null : fundSetPeriodFilterPojo.getRule();
        if (CollectionsUtil.isEmpty(rule)) {
            return null;
        }
        //下拉选项code - 账期设置
        Map<String, FundSetPeriodRulePojo> rulePojoMap = rule.stream().collect(Collectors.toMap(rulePojo -> rulePojo.getCode(), rulePojo -> rulePojo));
        String attr = fundSetPeriodFilterPojo.getAttr();
        String linkPeriod = ContractEnum.RECEIVABLE_PERIOD.getAttr();
        for (Map.Entry<String, FieldAttrEntity> entry : explainMap.entrySet()) {
            FieldAttrEntity fieldAttrEntity = entry.getValue();
            //考核字段
            if (Objects.equals(fieldAttrEntity.getAttr(), attr)) {
                List<ItemPoJo> items = fieldAttrEntity.getItems();
                if (CollectionUtils.isEmpty(items)) {
                    break;
                }
                for (ItemPoJo item : items) {
                    String code = item.getValue().toString();
                    //经销商端，只用“自主下单”
                    if (!Objects.equals(code, OrderTypeEnum.INDEPENDENT_ORDER.getCode())) {
                        continue;
                    }
                    FundSetPeriodRulePojo rulePojo = rulePojoMap.getOrDefault(code, new FundSetPeriodRulePojo());
                    ReceivablePeriodPojo receivablePeriodPojo = new ReceivablePeriodPojo(linkPeriod, rulePojo.getType(), rulePojo.getMonth(), rulePojo.getDay());
                    return receivablePeriodPojo;
                }
            }
        }
        return null;
    }

    /**
     * 获取导入时候默认账期的值,json字符串
     *
     * @param corpid 公司id
     * @param formId 表单id
     * @param jsonObject 导入的具体数据
     * @return
     * @throws XbbException
     */
    @Override
    public String getImportDefaultPeriod(String corpid, Long formId, JSONObject jsonObject) throws XbbException {
        return fundSetHelp.getImportDefaultPeriod(corpid, formId, jsonObject);
    }



    /**
     * 从缓存读取资金设置实体
     * 如果缓存不存在则从数据库读取出，再保存入缓存，方便后续直接从缓存读取使用
     * @param corpid 公司id
     * @param xbbRefTypeEnum 业务类型
     * @return com.xbongbong.saas.domain.entity.FundSetEntity
     * @author zcp
     * @since v1.0
     * @version v1.0
     */
    private FundSetEntity getToRedis(String corpid, XbbRefTypeEnum xbbRefTypeEnum){
        return fundSetModel.getToRedis(corpid, xbbRefTypeEnum);
    }

    /**
     * 把资金设置相关信息保存入缓存
     * @param corpid 公司id
     * @param setEntity 设置实体
     * @author zcp
     * @since v1.0
     * @version v1.0
     */
    private void saveSetInfoToRedis(String corpid, FundSetEntity setEntity){
        fundSetModel.saveSetInfoToRedis(corpid, setEntity);
    }




    /**
     * 判断是否（因条件设置不全）有账期及字段条件：true有，false无
     * 不仅要设置条件字段，还需对条件字段各个下拉选项设置默认账期
     * @param pojo
     * @param fieldAttrEntity
     * @return boolean
     * @throws XbbException
     * @author zcp
     * @since v1.0
     * @version v1.0
     */
    private boolean checkPeriod4Full(FundSetPeriodFilterPojo pojo, FieldAttrEntity fieldAttrEntity) throws XbbException {
        List<FundSetPeriodRulePojo> rule = pojo.getRule();
        if (CollectionsUtil.isEmpty(rule) || StringUtil.isEmpty(pojo.getAttr())) {
            //未设置订货单的默认账期
            throw new XbbException(FundsSetErrorCodeEnum.API_ERROR_248008, FundsSetErrorCodeEnum.API_ERROR_248008.getMsg(), pojo.getFormName());
        }
        //字段各个下拉选项都置账期
        if (Objects.nonNull(fieldAttrEntity)) {
            List<ItemPoJo> items = fieldAttrEntity.getItems();
            if (Objects.nonNull(items) && !Objects.equals(rule.size(), items.size())) {
                throw new XbbException(FundsSetErrorCodeEnum.API_ERROR_248009, FundsSetErrorCodeEnum.API_ERROR_248009.getMsg(), pojo.getFormName());
            }
        }
        boolean flag = true;
        for (FundSetPeriodRulePojo fundSetPeriodRulePojo : rule) {
            if (StringUtil.isEmpty(fundSetPeriodRulePojo.getCode())) {
                return false;
            }
            flag = FundSetHelp.checkPeriod(fundSetPeriodRulePojo);
            if (!flag) {
                return flag;
            }
        }
        return flag;
    }

    /**
     * 保存时条件校验、切换校验，及获取是否更改模式（有可能只是设置了账期条件，未更改模式）
     * @param fundSetPaymentSaveDTO 保存入参
     * @param modelTypeEnum 要改成的生成模式枚举
     * @param oldModelType 原生成规则
     * @return boolean true更改模式，false未更改模式
     * @throws XbbException
     * @author zcp
     * @since v1.0
     * @version v1.0
     */
    private boolean checkSet(FundSetPaymentSaveDTO fundSetPaymentSaveDTO, ModelTypeEnum modelTypeEnum, Long oldModelType) throws XbbException {
        if (Objects.isNull(modelTypeEnum)) {
            throw new XbbException(FundsSetErrorCodeEnum.API_ERROR_248001);
        }
        boolean changeModelFlag = !Objects.equals(oldModelType, fundSetPaymentSaveDTO.getModelType());
        if (changeModelFlag) {
            ModelTypeEnum oldModelTypeEnum = ModelTypeEnum.getByCode(oldModelType);
            XbbRefTypeEnum oldXbbRefTypeEnum = oldModelTypeEnum.getXbbRefTypeEnum();
            XbbRefTypeEnum newXbbRefTypeEnum = modelTypeEnum.getXbbRefTypeEnum();
            List<Integer> businessTypeList = new ArrayList<>();
            //回款计划无审批，回款单有审批
            XbbRefTypeEnum sheetXbbRefTypeEnum = XbbRefTypeEnum.PAYMENT_SHEET;
            businessTypeList.add(sheetXbbRefTypeEnum.getCode());
            boolean openWorkFlow = commonHelp.isOpenWorkFlow(fundSetPaymentSaveDTO.getCorpid());
            StringBuilder msg = new StringBuilder();
            if (!openWorkFlow) {
                //开启工作流的分开判断，会先判断回款单，不用再塞入回款单提示信息
                msg.append(sheetXbbRefTypeEnum.getName());
                msg.append(I18nMessageUtil.getMessage(I18nStringConstant.OR));
            }
            if (Objects.equals(newXbbRefTypeEnum.getCode(), ModelTypeEnum.PLAN.getXbbRefTypeEnum().getCode())) {
                businessTypeList.add(oldXbbRefTypeEnum.getCode());
                msg.append(oldXbbRefTypeEnum.getName());
            } else if(Objects.equals(oldXbbRefTypeEnum.getCode(), ModelTypeEnum.PLAN.getXbbRefTypeEnum().getCode())) {
                businessTypeList.add(newXbbRefTypeEnum.getCode());
                msg.append(newXbbRefTypeEnum.getName());
            } else {
                businessTypeList.add(oldXbbRefTypeEnum.getCode());
                businessTypeList.add(newXbbRefTypeEnum.getCode());
                msg.append(oldXbbRefTypeEnum.getName());
                msg.append(I18nMessageUtil.getMessage(I18nStringConstant.OR));
                msg.append(newXbbRefTypeEnum.getName());
            }
            //校验不能切换模式的条件，如果审批中有当前模式的回款单、发票、出库单，则不能切换模式：只校验当前模式上游业务类型、及要切换为的模式上游业务类型
            Map<String,Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put(ParameterConstant.CORPID, fundSetPaymentSaveDTO.getCorpid());
            param.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
            param.put("flowStatusIn", Arrays.asList(FlowStatusEnum.IN_APPROVAL.getType(), FlowStatusEnum.APPROVAL_PENDING.getType()));
            param.put("sysLong10", oldModelType);
            Integer count;
            if (openWorkFlow) {
                count = checkCount(ModelTypeEnum.PLAN, param);
                if (count > 0) {
                    //有回款单存在审批中
                    throw new XbbException(FundsSetErrorCodeEnum.API_ERROR_248004, String.format(I18nMessageUtil.getMessage(FundsSetErrorCodeEnum.API_ERROR_248004.getMsg()), XbbRefTypeEnum.PAYMENT_SHEET.getName(), modelTypeEnum.getName()));
                }
                // 工作流
                if (Objects.equals(newXbbRefTypeEnum.getCode(), ModelTypeEnum.PLAN.getXbbRefTypeEnum().getCode())) {
                    count = checkCount(oldModelTypeEnum, param);
                } else if(Objects.equals(oldXbbRefTypeEnum.getCode(), ModelTypeEnum.PLAN.getXbbRefTypeEnum().getCode())) {
                    count = checkCount(modelTypeEnum, param);
                } else {
                    count = checkCount(oldModelTypeEnum, param) + checkCount(modelTypeEnum, param);
                }
            } else {
                // 审批
                param.put("businessTypeIn", businessTypeList);
                param.put("start", 0);
                param.put("pageNum", 1);
                List<PaasProcessDataEntity> list = paasProcessDataModel.list(param);
                count = list.size();
            }
            if (count > 0) {
                throw new XbbException(FundsSetErrorCodeEnum.API_ERROR_248004, String.format(I18nMessageUtil.getMessage(FundsSetErrorCodeEnum.API_ERROR_248004.getMsg()), msg, modelTypeEnum.getName()));
            }
        }
        switch (modelTypeEnum) {
            case PLAN:
                //手动创建应收，默认无账期，不用设置其他任何条件
                return changeModelFlag;
            case INVOICE:
            case OUTSTOCK:
                ManageTypeEnum manageTypeEnum = ManageTypeEnum.getByCode(fundSetPaymentSaveDTO.getManageType());
                if (Objects.isNull(manageTypeEnum)) {
                    throw new XbbException(FundsSetErrorCodeEnum.API_ERROR_248002);
                }
                switch (manageTypeEnum) {
                    case CORP:
                        List<FundSetPeriodFilterPojo> periodFilter = fundSetPaymentSaveDTO.getPeriodFilter();
                        if (CollectionsUtil.isEmpty(periodFilter)) {
                            throw new XbbException(FundsSetErrorCodeEnum.API_ERROR_248003);
                        }
                        for (FundSetPeriodFilterPojo pojo : periodFilter) {
                            List<FundSetPeriodRulePojo> rule = pojo.getRule();
                            if (CollectionsUtil.isEmpty(rule)) {
                                //企业统一管理账期，未设置默认账期
                                throw new XbbException(FundsSetErrorCodeEnum.API_ERROR_248003);
                            }
                            FundSetPeriodRulePojo fundSetPeriodRulePojo = rule.get(0);
                            if (!FundSetHelp.checkPeriod(fundSetPeriodRulePojo)) {
                                throw new XbbException(FundsSetErrorCodeEnum.API_ERROR_248003);
                            }
                        }
                        break;
                    case CONTRACT:
                        //bugId：37285，订货单则校验必须设置下单类型字段的默认账期
                        periodFilter = fundSetPaymentSaveDTO.getPeriodFilter();
                        //订货单都需要限制必填
                        PaasFormExplainEntity orderExplain = paasFormExplainModel.getByBusinessType4Distributor(XbbRefTypeEnum.CONTRACT.getCode(), fundSetPaymentSaveDTO.getCorpid(), DistributorMarkEnum.DISTRIBUTOR.getCode());
                        if (Objects.isNull(orderExplain)) {
                            break;
                        }
                        Map<String, FieldAttrEntity> explainMap = ExplainUtil.getExplainMapByAttr(orderExplain.getExplains(), OrderEnum.TYPE.getAttr());
                        //下单类型字段实体
                        FieldAttrEntity fieldAttrEntity = explainMap.get(OrderEnum.TYPE.getAttr());
                        //订货单的formId
                        Long orderFormId = orderExplain.getFormId();
                        if (CollectionsUtil.isEmpty(periodFilter)) {
                            throw new XbbException(FundsSetErrorCodeEnum.API_ERROR_248003);
                        }
                        for (FundSetPeriodFilterPojo pojo : periodFilter) {
                            if (!Objects.equals(pojo.getFormId(), orderFormId)) {
                                continue;
                            }
                            if (!checkPeriod4Full(pojo, fieldAttrEntity)) {
                                throw new XbbException(FundsSetErrorCodeEnum.API_ERROR_248008, FundsSetErrorCodeEnum.API_ERROR_248008.getMsg(), pojo.getFormName());
                            }
                        }
                        break;
                    default:
                        //无账期、根据客户/合同管理账期暂时不做判断
                        break;
                }
                break;
            default:
                //不合法的modelType
                throw new XbbException(FundsSetErrorCodeEnum.API_ERROR_248006, FundsSetErrorCodeEnum.API_ERROR_248006.getMsg());
        }
        return changeModelFlag;
    }

    private Integer checkCount(ModelTypeEnum modelTypeEnum, Map<String, Object> param) {
        Integer count = 0;
        param.put("pageSize", 1);
        switch (modelTypeEnum) {
            case PLAN:
                List<PaymentSheetEntityExt> paymentSheetEntityExts = paymentSheetModel.findEntitysWithoutSub(param);
                count = paymentSheetEntityExts.size();
                break;
            case INVOICE:
                List<InvoiceEntityExt> invoiceEntityExts = invoiceModel.findEntitysWithoutSub(param);
                count = invoiceEntityExts.size();
                break;
            case OUTSTOCK:
                List<OutstockEntityExt> outstockEntityExts = outstockModel.findEntitysWithoutSub(param);
                count = outstockEntityExts.size();
                break;
            default:
                break;
        }
        return count;
    }

    /**
     * 切换模式或更改管理方式后，处理①客户、合同模板的应收账期字段；②销项发票的关联回款类型、回款单、应收款；③回款单、应收款的开票金额
     * @param fundSetPaymentSaveDTO 资金设置保存dto
     * @param corpid 公司id
     * @param modelTypeEnum 新模式枚举
     * @param changeModelFlag 是否更换模式flag
     * @param oldManageType 旧的管理方式
     * @throws XbbException
     * @author zcp
     * @since v1.0
     * @version v1.0
     */
    private void updateExplain(FundSetPaymentSaveDTO fundSetPaymentSaveDTO, String corpid, ModelTypeEnum modelTypeEnum, boolean changeModelFlag, Integer oldManageType) throws XbbException {
        Integer manageType = fundSetPaymentSaveDTO.getManageType();
        boolean changeManageFlag = !Objects.equals(oldManageType, manageType);
        if (changeModelFlag || changeManageFlag) {
            //客户、合同、销项发票、应收款、回款单
            List<Integer> specialBusinessList = fundSetHelp.getSpecialBusinessList();
            //查出客户、合同的模板解释
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put(StringConstant.CORPID, corpid);
            param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
            param.put("businessTypeIn", specialBusinessList);
            List<PaasFormExplainEntity> formExplainList = paasFormExplainModel.list(param);
            //处理explainEntity内的字段解释，把要更新的解释塞入该list
            List<PaasFormExplainEntity> updateList = fundSetHelp.handleSpecialExplain(false, modelTypeEnum, manageType, formExplainList);
            if (updateList.size() > 0) {
                paasFormExplainModel.updateBatchExplains(updateList, corpid);
            }
        }
    }

    @Override
    public PaasFormExplainEntity handleSpecialExplain(String corpid, PaasFormExplainEntity explainEntity) {
        //当前只处理业务：客户、合同、销项发票、应收款、回款单
        List<Integer> specialBusinessList = fundSetHelp.getSpecialBusinessList();
        if (!specialBusinessList.contains(explainEntity.getBusinessType())) {
            return explainEntity;
        }
        Long modelType = getModelType(corpid, XbbRefTypeEnum.CRM);
        Integer manageType = getManageType(corpid, XbbRefTypeEnum.CRM);
        ModelTypeEnum modelTypeEnum = ModelTypeEnum.getByCode(modelType);
        //处理explainEntity内的字段解释
        fundSetHelp.handleSpecialExplain(true, modelTypeEnum, manageType, Collections.singletonList(explainEntity));
        return explainEntity;
    }

    @Override
    public FundSetHandleExplainPojo getFundSetHandleExplainPojo4Init(FundSetTransitionPojo fundSetTransitionPojo, XbbRefTypeEnum xbbRefTypeEnum) {
        if (Objects.isNull(xbbRefTypeEnum)) {
            return null;
        }
        //当前只处理业务：客户、合同、销项发票、应收款、回款单
        List<Integer> specialBusinessList = fundSetHelp.getSpecialBusinessList();
        if (!specialBusinessList.contains(xbbRefTypeEnum.getCode())) {
            return null;
        }
        FundSetEntity fundSetEntity;
        if (Objects.isNull(fundSetTransitionPojo) || Objects.equals(fundSetTransitionPojo.getCorpid(), BasicConstant.ZERO_STRING) || StringUtil.isEmpty(fundSetTransitionPojo.getCorpid())) {
            //corpid=0，默认初始化为“手动创建应收”模式
            fundSetEntity = new FundSetEntity(XbbRefTypeEnum.CRM.getCode());
        }else {
            fundSetEntity = getToRedis(fundSetTransitionPojo.getCorpid(), XbbRefTypeEnum.CRM);
        }
        Long modelType = fundSetEntity.getSysLong10();
        ModelTypeEnum modelTypeEnum = ModelTypeEnum.getByCode(modelType);
        //各业务要处理的字段，后续如有其它字段要处理，则在此ExplainOpenCloseAttrPojo内增加和初始化
        FundSetHandleExplainPojo fundSetHandleExplainPojo = fundSetHelp.setFundSetHandleExplainPojo(false, modelTypeEnum, fundSetEntity.getManageType());
        return fundSetHandleExplainPojo;
    }

    @Override
    public void handleFieldEntity4Init(XbbRefTypeEnum xbbRefTypeEnum, FundSetHandleExplainPojo fundSetHandleExplainPojo, FieldAttrEntity fieldAttrEntity) {
        if (Objects.isNull(xbbRefTypeEnum) || Objects.isNull(fundSetHandleExplainPojo)) {
            return;
        }
        Map<Integer, Map<String, Integer>> openBusinessMap = fundSetHandleExplainPojo.getOpenBusinessMap();
        Map<Integer, Map<String, Integer>> closeBusinessMap = fundSetHandleExplainPojo.getCloseBusinessMap();

        Integer businessType = xbbRefTypeEnum.getCode();
        Map<String, Integer> openAttrMap = openBusinessMap.get(businessType);
        Map<String, Integer> closeAttrMap = closeBusinessMap.get(businessType);
        boolean emptyOpen = org.springframework.util.CollectionUtils.isEmpty(openAttrMap);
        boolean emptyClose = org.springframework.util.CollectionUtils.isEmpty(closeAttrMap);
        fundSetHelp.handleFieldEntity(openAttrMap, closeAttrMap, emptyOpen, emptyClose, false, fieldAttrEntity);
    }

    @Override
    public FundSetVO creditItem(BaseDTO baseDTO) throws XbbException{
        FundSetVO fundSetVO = new FundSetVO();
        CompanyConfigEntity entity = companyConfigModel.getByConfigAlias(CompanyConfigEnum.CREDIT_RULE.getAlias(), baseDTO.getCorpid());
        if (entity != null && Objects.equals(entity.getConfigValue(), "1")) {
            fundSetVO.setEnable(1);
        }
        return fundSetVO;
    }

    @Override
    public FundSetVO creditSave(FundSetDTO fundSetDTO) throws XbbException {
        FundSetVO fundSetVO = new FundSetVO();
        CompanyConfigEntity entity = companyConfigModel.getByConfigAlias(CompanyConfigEnum.CREDIT_RULE.getAlias(), fundSetDTO.getCorpid());
        if (entity == null) {
            entity = new CompanyConfigEntity();
            entity.setConfigName(CompanyConfigEnum.CREDIT_RULE.getName());
            entity.setConfigAlias(CompanyConfigEnum.CREDIT_RULE.getAlias());
            entity.setCorpid(fundSetDTO.getCorpid());
        }
        entity.setConfigValue(fundSetDTO.getEnable().toString());
        fundSetVO.setEnable(companyConfigModel.save(entity));
        return fundSetVO;
    }

    @Override
    public FundSetPaymentItemVO statementItem(BaseDTO baseDTO) throws XbbException {
        FundSetPaymentItemVO fundSetPaymentItemVO = new FundSetPaymentItemVO();
        String corpid = baseDTO.getCorpid();
        FundSetEntity setEntity = fundSetModel.getByRefType(corpid, XbbRefTypeEnum.CRM.getCode(), FundSetMenuEnum.RECONCILIATION_RULE.getType());
        if (setEntity != null) {
            BeanUtil.copyProperties(setEntity, fundSetPaymentItemVO);
            List<FundSetPeriodFilterPojo> periodFilter = JSONArray.parseArray(setEntity.getPeriodFilter(), FundSetPeriodFilterPojo.class);
            if (Objects.equals(setEntity.getManageType(), ManageTypeEnum.CORP.getCode())) {
                fundSetPaymentItemVO.setPeriodFilter(periodFilter);
            } else {
                List<FundSetPeriodFilterPojo> periodFilterView = new ArrayList<>();
                Map<Long, FundSetPeriodFilterPojo> formFilterMap = periodFilter.stream().collect(Collectors.toMap(FundSetPeriodFilterPojo::getFormId, pojo -> pojo));
                List<PaasFormEntityExt> paasFormEntityExtList = paasFormModel.getEnableFormList(corpid, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode());
                for (PaasFormEntityExt entityExt : paasFormEntityExtList) {
                    Long formId = entityExt.getId();
                    FundSetPeriodFilterPojo fundSetPeriodFilterPojo = formFilterMap.getOrDefault(formId, new FundSetPeriodFilterPojo());
                    fundSetPeriodFilterPojo.setFormId(entityExt.getId());
                    fundSetPeriodFilterPojo.setFormName(entityExt.getName());
                    periodFilterView.add(fundSetPeriodFilterPojo);
                }
                fundSetPaymentItemVO.setPeriodFilter(periodFilterView);
            }
        } else {
            List<FundSetPeriodFilterPojo> periodFilter = new ArrayList<>();
            List<FundSetPeriodRulePojo> rule = new ArrayList<>();
            FundSetPeriodRulePojo fundSetPeriodRulePojo = new FundSetPeriodRulePojo(1,1,1,StringConstant.LAST);
            rule.add(fundSetPeriodRulePojo);
            FundSetPeriodFilterPojo filterPojo = new FundSetPeriodFilterPojo();
            filterPojo.setRule(rule);
            periodFilter.add(filterPojo);
            fundSetPaymentItemVO.setPeriodFilter(periodFilter);
            fundSetPaymentItemVO.setManageType(ManageTypeEnum.CORP.getCode());
        }
        List<KeyAndValuePojo> manageTypeItem = new ArrayList<>();
        for (ManageTypeEnum cache : ManageTypeEnum.getStatementRule()) {
            KeyAndValuePojo keyAndValuePojo = new KeyAndValuePojo(cache.getCode().longValue(), cache.getName());
            manageTypeItem.add(keyAndValuePojo);
        }
        fundSetPaymentItemVO.setManageTypeItem(manageTypeItem);
        return fundSetPaymentItemVO;
    }

    @Override
    public FundSetVO statementSave(FundSetPaymentSaveDTO fundSetPaymentSaveDTO) throws XbbException {
        FundSetVO fundSetVO = new FundSetVO();
        String corpid = fundSetPaymentSaveDTO.getCorpid();
        FundSetEntity setEntity = fundSetModel.getByRefType(corpid, XbbRefTypeEnum.CRM.getCode(), FundSetMenuEnum.RECONCILIATION_RULE.getType());
        if (setEntity == null) {
            setEntity = new FundSetEntity(XbbRefTypeEnum.CRM.getCode(),FundSetMenuEnum.RECONCILIATION_RULE.getType());
            setEntity.setCorpid(corpid);
        }
        setEntity.setManageType(fundSetPaymentSaveDTO.getManageType());
        setEntity.setEnable(fundSetPaymentSaveDTO.getEnable());
        setEntity.setPeriodFilter(JSON.toJSONString(fundSetPaymentSaveDTO.getPeriodFilter()));
        setEntity.setCreatorId(fundSetPaymentSaveDTO.getUserId());
        fundSetVO.setEnable(fundSetModel.save(setEntity));
        return fundSetVO;
    }

    @Override
    public FundSetVO writeOffItem(BaseDTO baseDTO) throws XbbException {
        FundSetVO fundSetVO = new FundSetVO();
        CompanyConfigEntity entity = companyConfigModel.getByConfigAlias(CompanyConfigEnum.WRITE_OFF_RULE.getAlias(), baseDTO.getCorpid());
        if (entity != null && Objects.equals(entity.getConfigValue(), "1")) {
            fundSetVO.setSort(1);
        }
        return fundSetVO;
    }

    @Override
    public FundSetVO writeOffSave(FundSetDTO fundSetDTO) throws XbbException {
        FundSetVO fundSetVO = new FundSetVO();
        CompanyConfigEntity entity = companyConfigModel.getByConfigAlias(CompanyConfigEnum.WRITE_OFF_RULE.getAlias(), fundSetDTO.getCorpid());
        if (entity == null) {
            entity = new CompanyConfigEntity();
            entity.setConfigName(CompanyConfigEnum.WRITE_OFF_RULE.getName());
            entity.setConfigAlias(CompanyConfigEnum.WRITE_OFF_RULE.getAlias());
            entity.setCorpid(fundSetDTO.getCorpid());
        }
        entity.setConfigValue(fundSetDTO.getSort().toString());
        fundSetVO.setSort(companyConfigModel.save(entity));
        return fundSetVO;
    }

    @Override
    public FundSetPayListVO payList(BaseDTO baseDTO) throws XbbException {
        FundSetPayListVO payListVO = new FundSetPayListVO();
        List<FundSetPayPojo> list = new ArrayList<>();
        String corpid = baseDTO.getCorpid();
        List<PayMethodFundSetEnum> payMethodEnums = Arrays.asList(PayMethodFundSetEnum.WECHAT, PayMethodFundSetEnum.OFFLINE);
        for (PayMethodFundSetEnum payMethodEnum : payMethodEnums) {
            FundSetPayPojo payPojo = new FundSetPayPojo();
            JSONObject button = new JSONObject();
            BeanUtil.copyProperties(payMethodEnum, payPojo);
            CompanyConfigEntity entity = companyConfigModel.getByConfigAlias(payMethodEnum.getAlias(), corpid);
            if (Objects.equals(payMethodEnum, PayMethodFundSetEnum.WECHAT)) {
                button.put("name", "申请开通");
                String weChatApplyUrl = ProBaseConfig.getWeChatApplyUrl();
                button.put("openUrl", weChatApplyUrl);
            } else {
                button.put("name", "设置");
            }
            payPojo.setButton(button);
            if (entity != null && StringUtil.isNotEmpty(entity.getConfigValue())) {
                FundSetPayPojo pojo = JSON.parseObject(entity.getConfigValue(), FundSetPayPojo.class);
                JSONArray info = new JSONArray();
                if (payMethodEnum == PayMethodFundSetEnum.OFFLINE) {
                    payPojo.setStatus(1);
                    JSONObject accountName = new JSONObject();
                    accountName.put("key", "账户名称");
                    accountName.put("text", pojo.getAccountName());
                    info.add(accountName);
                    JSONObject accountBank = new JSONObject();
                    accountBank.put("key", "开户银行");
                    accountBank.put("text", pojo.getAccountBank());
                    info.add(accountBank);
                    JSONObject accountId = new JSONObject();
                    accountId.put("key", "银行账户");
                    accountId.put("text", pojo.getAccountId());
                    info.add(accountId);
                }

                payPojo.setInfo(info);
                payPojo.setEnable(pojo.getEnable());
            } else {
                payPojo.setStatus(0);
                payPojo.setEnable(0);
            }
            list.add(payPojo);
        }

        payListVO.setList(list);
        return payListVO;
    }

    @Override
    public FundSetPayVO payItem(FundSetPayDTO fundSetPayDTO) throws XbbException {
        FundSetPayVO payVO = new FundSetPayVO();
        CompanyConfigEntity entity = companyConfigModel.getByConfigAlias(fundSetPayDTO.getAlias(), fundSetPayDTO.getCorpid());
        if (entity != null) {
            payVO = JSON.parseObject(entity.getConfigValue(), FundSetPayVO.class);
        }
        if (Objects.equals(fundSetPayDTO.getAlias(), PayMethodFundSetEnum.ALIPAY.getAlias())) {
            //TODO 密钥是固定的,是否存配置中还是数据库中
            payVO.setSecretKey("abc");
        }
        return payVO;
    }

    @Override
    public FundSetVO paySave(FundSetPaySaveDTO fundSetPaySaveDTO) throws XbbException {
        FundSetVO fundSetVO = new FundSetVO();
        String alias = fundSetPaySaveDTO.getAlias();
        String corpid = fundSetPaySaveDTO.getCorpid();
        String name = fundSetPaySaveDTO.getName();
        try {
            FundSetPayPojo payPojo = new FundSetPayPojo();
            CompanyConfigEntity entity = companyConfigModel.getByConfigAlias(alias, corpid);
            BeanUtil.copyProperties(fundSetPaySaveDTO, payPojo);
            if (entity == null) {
                entity = new CompanyConfigEntity();
                entity.setCorpid(corpid);
                entity.setConfigAlias(alias);
                entity.setConfigName(name);
            }
            entity.setConfigValue(JSON.toJSONString(payPojo));
            companyConfigModel.save(entity);
            fundSetVO.setAlias(alias);
        } catch (Exception e) {
            throw new XbbException(ErrorCodeEnum.API_FAIL);
        }
        return fundSetVO;
    }

    @Override
    public FundSetVO payEnable(FundSetDTO fundSetDTO) throws XbbException {
        FundSetVO fundSetVO = new FundSetVO();
        String alias = fundSetDTO.getAlias();
        JSONObject value = new JSONObject();
        CompanyConfigEntity entity = companyConfigModel.getByConfigAlias(alias, fundSetDTO.getCorpid());
        if (entity != null && StringUtil.isNotEmpty(entity.getConfigValue())){
            value = JSON.parseObject(entity.getConfigValue());
        } else {
            entity = new CompanyConfigEntity();
            CompanyConfigEnum companyConfigEnum = CompanyConfigEnum.getByAlias(alias);
            entity.setCorpid(fundSetDTO.getCorpid());
            entity.setConfigAlias(alias);
            entity.setConfigName(companyConfigEnum.getName());
            entity.setConfigAlias(alias);
        }
        value.put("enable", fundSetDTO.getEnable());
        entity.setConfigValue(JSON.toJSONString(value));
        companyConfigModel.save(entity);
        fundSetVO.setEnable(fundSetDTO.getEnable());
        return fundSetVO;
    }


}
